/*--------------------------------------------------------------------------------
file: Msg.h
use	: 封装一个Msg类。
ver :
	1.0 by whc. at 2014-10-26. anything call me.
memo:
	Msg = Message

	*： 消息头前缀
	L2C_  		: 代表 LoginServer 	to Client
	C2L_ 		: 代表 Client 		to LoginServer
	C2G_ 		: 代表 Client 		to GameServer
	G2C_ 		: 代表 GameServer 	to Client
	L2W_ 		: 代表 LoginServer 	to WorldServer
	W2L_ 		: 代表 WorldServer 	to LoginServer
	G2W_ 		: 代表 GameServer 	to WorldServer
	W2G_ 		: 代表 WorldServer 	to GameServer
--------------------------------------------------------------------------------*/


#ifndef MSG_H
#define MSG_H

#include <memory.h>
#include <string>
#include <iostream>
#include "Common.h"
#include "Debug.h"
//#include "TcpServer.h"

using namespace std;
#define MSG_LEN_MAX 640 												// 每个消息最大长度
#define MSG_BLOCK 100 													// 将消息安功能分段 每段的间隔 100
#define MSG_CHAPTER_BLOCK 20000 										// 消息大段 按照收发方向分段


#define MSG_C2G_BEGIN (0*MSG_CHAPTER_BLOCK)
#define MSG_C2G_END (MSG_C2G_BEGIN + MSG_CHAPTER_BLOCK - 1)

#define MSG_G2C_BEGIN (1*MSG_CHAPTER_BLOCK)
#define MSG_G2C_END (MSG_G2C_BEGIN + MSG_CHAPTER_BLOCK - 1)

#define MSG_C2L_BEGIN (2*MSG_CHAPTER_BLOCK)
#define MSG_C2L_END (MSG_C2L_BEGIN + MSG_CHAPTER_BLOCK - 1)

#define MSG_L2C_BEGIN (3*MSG_CHAPTER_BLOCK)
#define MSG_L2C_END (MSG_L2C_BEGIN + MSG_CHAPTER_BLOCK - 1)

#define MSG_W2L_BEGIN (4*MSG_CHAPTER_BLOCK)
#define MSG_W2L_END (MSG_W2L_BEGIN + MSG_CHAPTER_BLOCK - 1)

#define MSG_L2W_BEGIN (5*MSG_CHAPTER_BLOCK)
#define MSG_L2W_END (MSG_L2W_BEGIN + MSG_CHAPTER_BLOCK - 1)

#define MSG_G2W_BEGIN (6*MSG_CHAPTER_BLOCK)
#define MSG_G2W_END (MSG_G2W_BEGIN + MSG_CHAPTER_BLOCK - 1)

#define MSG_W2G_BEGIN (7*MSG_CHAPTER_BLOCK)
#define MSG_W2G_END (MSG_W2G_BEGIN + MSG_CHAPTER_BLOCK - 1)

#define MSG_SYS_BEGIN (8*MSG_CHAPTER_BLOCK)
#define MSG_SYS_END (MSG_SYS_BEGIN + MSG_CHAPTER_BLOCK - 1)

#define MSG_CMD_MIN 0 													// 消息最小cmd
#define MSG_CMD_MAX (9*MSG_CHAPTER_BLOCK - 1) 							// 消息最大cmd



// 消息头。
enum class eCmd{
	/// <summary>
	/// C2G Message
	/// </summary>
    C2G = MSG_C2G_BEGIN,
    C2G_Role = MSG_C2G_BEGIN + MSG_BLOCK * 0x00,
    C2G_Role_Info,
    C2G_Role_Create, 													// 创建角色
	C2G_MainPlayer_Info,                                                // 请求主玩家数据
	C2G_Role_Data, 														// 请求角色数据

    C2G_ChangeSence = MSG_C2G_BEGIN + MSG_BLOCK * 0x01,   				// 切换场景消息段
    C2G_Enter_Main,                                                     // 请求进入主场景


	/// <summary>
	/// G2C Message
	/// </summary>
    G2C = MSG_G2C_BEGIN,
    G2C_Role = MSG_G2C_BEGIN + MSG_BLOCK * 0x00,
    G2C_Role_Info,
    G2C_Role_Create_Ret, 												// 角色创建返回
	G2C_MainPlayer_Info,                                                // 主玩家数据返回
    G2C_Role_Data, 														// 角色数据

	G2C_ChangeSence = MSG_G2C_BEGIN + MSG_BLOCK * 0x01,   				// 切换场景消息段
    G2C_Enter_Main_Ret,                                                 // 返回进入主场景



	/// <summary>
	/// C2L Message
	/// </summary>
	C2L = MSG_C2L_BEGIN,
    C2L_Login = MSG_C2L_BEGIN + MSG_BLOCK * 0x00,                       // 登录消息段
    C2L_Login_Login,                                                    // 登录
	C2L_Login_Info, 													// 客户端信息返回
	C2L_Login_ServerInfo,												// 客户端请求服务器信息
    C2L_Login_Register,                                                 // 注册

	/// <summary>
	/// L2C Message
	/// </summary>
	L2C = MSG_L2C_BEGIN,
    L2C_Login = MSG_L2C_BEGIN + MSG_BLOCK * 0x00,         				// 登录消息段
    L2C_Login_Login_Ret, 												// 登录返回
    L2C_Login_Info, 													// 请求客户端信息
    L2C_Login_ServerInfo,												// 发送服务器信息到客户端
    L2C_Login_RegisterRet,                                              // 注册返回

	/// <summary>
	/// W2L Message
	/// </summary>
	W2L = MSG_W2L_BEGIN,
	W2L_Login = MSG_W2L_BEGIN + MSG_BLOCK * 0x00,
	W2L_Login_Info, 													// 服务器信息返回
	W2L_Login_Info_Update,												// 服务器登录信息更新

	/// <summary>
	/// L2W Message
	/// </summary>
	L2W = MSG_L2W_BEGIN,
	L2W_Login = MSG_L2W_BEGIN + MSG_BLOCK * 0x00,
	L2W_Login_Info, 													// 请求服务器信息返回

	/// <summary>
	/// G2W Message
	/// </summary>
	G2W = MSG_G2W_BEGIN,
	G2W_Login = MSG_G2W_BEGIN + MSG_BLOCK * 0x00,
	G2W_Login_Info,
	G2W_Login_Role_Info, 												// 询问角色信息
	G2W_Player_Create, 													// 创建玩家


	/// <summary>
	/// W2G Message
	/// </summary>
	W2G = MSG_W2G_BEGIN,
	W2G_Login = MSG_W2G_BEGIN + MSG_BLOCK * 0x00,
	W2G_Login_Info,
	W2G_Login_Role_Info, 												// 玩家信息返回
	W2G_Player_Create, 													// 创建玩家返回


	/// <summary>
	/// SYS Message
	/// 不分方向, 向链接的都发
	/// </summary>
	SYS = MSG_SYS_BEGIN,
	SYS_Check = MSG_SYS_BEGIN + MSG_BLOCK * 0x00, 						// 系统消息段
	SYS_Check_Ask, 														// 询问每个链接的客户端, 是不是我们要服务的客户端
	SYS_Check_Answer,													// 回答


};

class MsgQunue;// extern 

class Message
{
private:



public:
	Message(int _fd);
	Message(int _fd, eCmd _cmd);
	Message(const Message & _Msg);
	~Message();


	//
	static void Send(MsgQunue* _pMsgQunue, Message* _pMsg);

	bool CheckCmd();


	// 将mp_buf 反序列化
	void Decode(char * _buf, size_t _len);

	// 将mp_buf 序列化
	void Encode();


	//
	char * GetBuf();

	///
	//
	char GetChar();
	void AddChar(char _value);

	//
	std::string GetString();
	void AddString(std::string _value);

	//
	short GetShort();
	void AddShort(short _value);

	//
	int GetInt();
	void AddInt(int _value);

	//
	long long GetLong();
	void AddLong(long long _value);

	//
	float GetFloat();
	void AddFloat(float _value);

	//
	bool GetBool();
	void AddBool(bool _value);

public:

	int m_fd;
	size_t m_len;
	eCmd m_cmd; 			// 消息ID
	int m_pos;

private:

	char * mp_content; 			// 消息内容缓冲区指针 include starBuf and endBuf

};

union alen{
	char a[4] = {0};
	int i;
};

union astrLen{
	char a[2] = {0};
	short s;
};

union ai{
	char a[4] = {0};
	int i;
};

union af{
	char a[4] = {0};
	float f;
};

union al{
	char a[8] = {0};
	long long l;
};

union as{
	char a[2] = {0};
	short s;
};


#endif // MSG_H
